package com.statemachine;

import com.generic.genericinterface.demo1.Generator;

public class VendingMachine {

	// 初始状态
	private static State state = State.RESTING;
	private static int amount = 0;
	// 当前选择的物品
	private static Input selection = null;

	enum StateDuration {
		TRANSIENT
	}

	enum State {
		// 开始状态
		RESTING {
			@Override
			void next(Input input) {
				switch (Category.categorize(input)) {
				case MONEY:
					amount += input.amount();
					state = ADDING_MONEY;
					break;
				case SHUT_DOWN:
					state = TERMINAL;
				default:
				}
			}
		},
		// 加钱
		ADDING_MONEY {
			@Override
			void next(Input input) {
				switch (Category.categorize(input)) {
				case MONEY:
					amount += input.amount();
					break;
				case ITEM_SELECTION:
					selection = input;
					if (amount < selection.amount()) {
						System.out.println("Insufficient money for "
								+ selection);
					} else {
						state = DISPENSING;
					}
					break;
				case QUIT_TRANSACTION:
					state = GIVING_CHANGE;
					break;
				case SHUT_DOWN:
					state = TERMINAL;
				default:
				}
			}
		},
		// 分发
		DISPENSING(StateDuration.TRANSIENT) {
			@Override
			void next() {
				System.out.println("here is your " + selection);
				amount -= selection.amount();
				state = GIVING_CHANGE;
			}
		},
		// 找钱
		GIVING_CHANGE(StateDuration.TRANSIENT) {
			@Override
			void next() {
				if (amount > 0) {
					System.out.println("Your change:" + amount);
					amount = 0;
				}
				state = RESTING;
			}
		},
		// 停止
		TERMINAL {
			@Override
			void output() {
				System.out.println("Halted");
			}
		};

		// 是否是瞬时状态
		private boolean isTransient = false;

		State() {
			System.out.println("初始化");
		}

		State(StateDuration trans) {
			System.out.println("初始化2");
			isTransient = true;
		}

		void next(Input input) {
			throw new RuntimeException(
					"only call next(Input input) for non-transient states");
		}

		void next() {
			throw new RuntimeException(
					"only call next() for StateDuration.TRANSIENT states");
		}

		void output() {
			System.out.println(amount);
		}

	}

	static void run(Generator<Input> gen) {
		while (state != State.TERMINAL) {
			state.next(gen.next());
			while (state.isTransient) {
				state.next();
			}
			state.output();
		}
	}

	public static void main(String[] args) {
		System.out.println("开始");
		Generator<Input> gen = new RandomInputGenerator();
		run(gen);
		System.out.println("结束");
	}

}
